import { Input } from '../input/input';
import { DATA } from '../symbol';
import time from '@knno/time';
import SVGDate from '@mdi/svg/svg/calendar-blank.svg';
// import SVGDate from '@material-design-icons/svg/filled/calendar_today.svg';
import SVGDateRange from '@material-design-icons/svg/filled/date_range.svg';
import SVGArrowDown from '@material-design-icons/svg/filled/keyboard_arrow_down.svg';
import SVGTime from '@material-design-icons/svg/filled/access_time.svg';
import { DateMode, DatePicker } from '../datePicker/datePicker';
import { CalDataBase, DateValue, dateValue } from '../calendar/calendar';
import { T } from '@knno/i18n';
import { clone } from '../../tools/sugar';

export interface Datebox extends CalDataBase {
	[DATA]: {
		shown: boolean;
		/**
		 * dy: accurate to year
		 * dm: accurate to month
		 * dd: accurate to day
		 * th: accurate to hour
		 * tm: accurate to minute
		 * ts: accurate to second
		 * dd+th: date accurate to day and time accurate to hour
		 * dd+tm: date accurate to day and time accurate to minute
		 * dd+ts: date accurate to day and time accurate to second
		 */
		mode: DateMode;
		/**
		 * If precision is hour, minute or second then force use roller as the picker.
		 */
		useRoller: boolean;
		isRange: boolean;
		selected: Date[];
		prefixIcon: boolean;
	};
}

export class Datebox extends Input {
	constructor() {
		super();
		this[DATA].selected = [];
		this[DATA].useRoller = false;
		this[DATA].isRange = false;
		this[DATA].prefixIcon = false;
		super.addClass('select');
		super.suffixIcon(SVGDate);
		this.mode('dd');
		this.query('input').attr('readonly', true);
		this.on('click', this.openSelect.bind(this));
		this.on('keyup', (evt) => {
			if (evt.key === 'Space' || evt.key === ' ') {
				this.openSelect();
			}
		});
	}

	private getText(): string {
		if (this[DATA].selected.length === 0) return '';
		let pattern: string;
		if (this[DATA].mode === 'dy') {
			pattern = 'yyyy';
		} else if (this[DATA].mode === 'dm') {
			pattern = 'yyyy-MM';
		} else if (this[DATA].mode === 'dd') {
			pattern = 'yyyy-MM-dd';
		} else if (this[DATA].mode === 'dd+th') {
			pattern = 'yyyy-MM-dd HH';
		} else if (this[DATA].mode === 'dd+tm') {
			pattern = 'yyyy-MM-dd HH:mm';
		} else if (this[DATA].mode === 'dd+ts') {
			pattern = 'yyyy-MM-dd HH:mm:ss';
		} else if (this[DATA].mode === 'th') {
			pattern = 'HH';
		} else if (this[DATA].mode === 'tm') {
			pattern = 'HH:mm';
		} else {
			pattern = 'HH:mm:ss';
		}
		if (this[DATA].isRange) {
			const d1 = time.format(this[DATA].selected[0], pattern);
			const d2 = time.format(this[DATA].selected[1], pattern);
			if (d1 === null || d2 === null) return '';
			if (d1 === d2) {
				return d1;
			} else {
				return `${d1}  ${T`~`}  ${d2}`;
			}
		} else {
			return time.format(this[DATA].selected[0], pattern) ?? '';
		}
	}

	override clear(): this {
		this.value(null);
		return this;
	}

	private setSuffix() {
		if (this[DATA].prefixIcon) {
			this.suffixIcon(SVGArrowDown);
		} else if (/t/.test(this[DATA].mode)) {
			this.suffixIcon(SVGTime);
		} else {
			if (this.range()) {
				this.suffixIcon(SVGDateRange);
			} else {
				this.suffixIcon(SVGDate);
			}
		}
	}

	openSelect() {
		if (this.readonly() || this.disabled()) return;
		DatePicker.show({
			refer: this,
			date: this[DATA].selected,
			range: this[DATA].isRange,
			mode: this[DATA].mode,
			focus: true,
		}).onSelect((value) => {
			this.value(value);
			this.emit(new Event('change'));
		});
	}

	roller(): boolean;
	roller(value: boolean): this;
	roller(value?: boolean): this | boolean {
		if (value === undefined) {
			return this[DATA].useRoller;
		}
		this[DATA].useRoller = value;
		return this;
	}

	range(): boolean;
	range(value: boolean): this;
	range(value?: boolean): this | boolean {
		if (value === undefined) {
			return this[DATA].isRange;
		}
		this[DATA].isRange = value;
		this.setSuffix();
		super.value(this.getText());
		return this;
	}

	mode(): DateMode;
	mode(value: DateMode): this;
	mode(value?: DateMode): this | DateMode {
		if (value === undefined) {
			return this[DATA].mode;
		}
		this[DATA].mode = value;
		this.setSuffix();
		super.value(this.getText());
		return this;
	}

	override value(): Date[] | Date | null;
	override value(val: DateValue[] | DateValue | null): this;
	override value(val?: DateValue[] | DateValue | null): this | Date[] | Date | null {
		if (val === undefined) {
			return clone(dateValue(this[DATA]));
		}
		dateValue(this[DATA], val);
		super.value(this.getText());
		return this;
	}

	override text(): string;
	override text(text: string): this;
	override text(text?: string): this | string {
		if (typeof text === 'string') {
			return this;
		}
		return this.getText();
	}

	override readonly(): boolean;
	override readonly(value: boolean): this;
	override readonly(value?: boolean | undefined): boolean | this {
		if (value === undefined) {
			return this.attr('readonly') != null;
		}
		this.attr('readonly', value);
		this.query('input').attr('readonly', true);
		return this;
	}

	override prefixIcon(icon: string | null): this {
		super.prefixIcon(icon);
		this[DATA].prefixIcon = !!icon;
		this.setSuffix();
		return this;
	}
}

export function datebox(...className: string[]): Datebox {
	return new Datebox().addClass(...className);
}
